iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
1
自我挑戰組

關於 Ruby on Rails 的那些事系列 第 24

Day 24 - Devise 會員系統 - 貳

  • 分享至 

  • xImage
  •  

接著昨天未完部分繼續說~
建立完前置作業就可以在專案中進行囉!
要先知道的是 devise 到底幫我們做了什麼?還有怎麼使用這個驗證?

Controller filters 和 helpers

Devise 將會建立一些 helpers,讓我們可以在 controllers 和 views 裡面使用方法。假設要在某個 controller 設定會員驗證,只要加 before_action... 就可以達成!

小提醒:以下範例是假設建立的 model 名稱為 User,如果是 Admin 請自行更換!

# controller.rb
class ArticleController < ApplicationController
  before_action :authenticate_user! # 將會限制這個controller的權限
  
  def index
    @articles = @Article.all
  end
  
  # 略...
end

判斷使用者是否登入?

user_signed_in?

當使用者登入後,就可以用這個 helper 找當前使用者是誰?

current_user

在這個 scope 可以使用 session

user_session

當使用者登入的瞬間,devise 確認帳戶或更新密碼之後,會去找 scope 的路徑。
就是登入後,要把使用者導向哪個地方。
當使用了 :user 的 resources,就會去 user_root_path,如果沒有設定這條路徑,則會使用 root_path 為預設值!
還記得昨天安裝後,跳出提醒的事項嗎?其中有一條要求就是確認 routes.rb 中得設定 root_path 要導向哪裡

root to: "home#index"

model 的設定

昨天提到彈性功能部分,可以客製化的增加或減少,如果有增加 Confirmable、Recoverable、Registerable 等功能,在設定 model 時,可以再額外加入對模組的特殊選項,只要把選項掛在模組後面就可以了!(例如:密碼加密的演算法、允許多少次帳密輸入錯誤次數、多久時間未操作及登出...)
像這樣:

# user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :Confirmable, stretches: ...
end

除了:stretches,還可以設定 :pepper, :encryptor, :confirm_within, :remember_for, :timeout_in, :unlock_in...
詳細的文件在安裝套件的時候 Devise 就已經送給我們了,可以打開 config/initializers/devise.rb 參考裡面的說明。

強參數 Strong Parameters

RoR 為了避免使用者在填入資料時,惡意或不小心帶入其他參數,在使用者送出表單資料的時候,controller 接到 params(一包表單資料),先檢驗一下有沒有問題。
就像進口貨物過海關一樣,一大個貨櫃中只有合法的貨才能過關,不合法的東西會被查扣丟掉。而 devise 預設只有建立兩個欄位可以通過,分別是 email 和 password,但很多時候會要求其他資料,例如姓名、匿稱、生日、地址等,這時候就要處理強參數的問題,否則會被 controller 擋在門外。

在 Devise 中只有三個 action 允許設定的欄位通過傳到 model,
分別是:

  • sign_in ( Devise::SessionsController#create )
    只允許 authentication keys 通過( ex: email、account)
  • sign_up ( Devise::RegistrationsController#create )
    只允許 authentication keys、password、password_confirmation
  • account_update ( Devise::RegistrationsController#update )
    只允許 authentication keys、password、password_confirmation、 current_password

我希望使用者註冊表單再額外多加一個欄位 nickname、address、
bitthday,因此必須在 ApplicationController 設定 before_action
(如果是簡易的欄位,可以採用單行的設計。
但是如果是比較複雜的欄位,則有巢狀的設計方式)

# ApplicationController.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    # 單行的設計方式
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
    
    # 巢狀的設計方式
    devise_parameter_sanitizer.permit(:sign_up,
      keys:[
        address_attributes: [
          :country,
          :state,
          :city,
          :area,
          :postal_code
        ]
        :birthday: [
          :year, 
          :month, 
          :day
        ]
      ]
  end
end

第三行 => 表示「設定自定義欄位可被通過」,前提是得由 devise 產生的 controller 才行
https://ithelp.ithome.com.tw/upload/images/20201009/20129258LOekCTTebs.png

參考資料:
Devise 快速上手
Devise - GitHub

學無止盡,每天都要進步一點點!


上一篇
Day 23 - Devise 會員系統 - 壹
下一篇
Day 25 - Devise 會員系統 - 客製化
系列文
關於 Ruby on Rails 的那些事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言